import {v4 as uuidv4} from "uuid";

export default class Socket {
    /**
     * @type {null | WebSocket}
     */
    #socket = null;

    #messageHandler=new Map();

    constructor(url) {
        this.#socket = new WebSocket(url);

        this.#socket.onopen = () => {
            console.log("WebSocket created");
        }
        this.#socket.onerror = (event) => {
            console.error("WebSocket create failed", event);
        }

        this.#socket.onclose = () => {
            console.log("WebSocket closed");
        }

        this.#socket.onmessage=event=>{
            const response=JSON.parse(event.data);
            const {code,uuid}=response;

            if(code===1){
                const {data}=response;
                
                if(this.#messageHandler.has(uuid)){
                    
                    this.#messageHandler.get(uuid)(data);
                    this.#messageHandler.delete(uuid);
                }

            }else{
                console.error("Receive message error");
            }
        }
    }

    /**
     * 返回WebSocket是否连接
     * 
     * @returns {boolean}
     */
    isOpen = () => {
        return this.#socket && this.#socket.readyState === WebSocket.OPEN;
    };

    /**
     * 关闭socket连接
     */
    close = () => {
        if (this.#socket) this.#socket.close();
    }

    // getSocket=()=>this.#socket;

    /**
     * 
     * 向后端发送数据，返回Promise，注意异步操作
     * 
     * @param {Object} data 发送的数据
     * @returns {Promise}
     */
    send = (data) => {
        return new Promise((resolve,reject)=>{
            if (this.isOpen()) {
                // console.log("Sending data:", data);
                const uuid=uuidv4();
                
                const params={
                    uuid,
                    data
                }
                
                this.#messageHandler.set(uuid,resolve);
                this.#socket.send(JSON.stringify(params));
            } else {
                reject(new Error("WebSocket is not open"));
            }

        });
    }

}